#include<iostream>
#include<functional>
#include<vector>
#include<sys/types.h>
#include<sys/wait.h>
#include<signal.h>
#include<unistd.h>

//要实现在没有信号的时候pending表全0，
//收到2号信号指定位置为1，然后block没设置的时候全0
//屏蔽后指定位图为1，然后验证2号信号递达pending从0变1

void PrintPending(sigset_t &pending)
{
    std::cout << "[pid: " << getpid() << "] " << "sigpending list: ";
    // 右->左， 低->高 ， 0000 0000
    for (int signo = 31; signo > 0; signo--)
    {
        if (sigismember(&pending, signo))
        {
            std::cout << "1";
        }
        else
        {
            std::cout << "0";
        }
    }
    std::cout << "\r\n";
}

void handler(int signo)
{
    std::cout << "我获取到了: " << signo << " 信号" << std::endl;
    // 不要让进程终止
    // 在对2号信号捕捉的代码中，获取pending && 打印？？
    sigset_t pending;
    sigemptyset(&pending);
    // 2.1 获取当前进程的pending信号集
    sigpending(&pending);

    // 2.2 不断打印所有的pending信号集中的信号
    std::cout << "###########################" << std::endl;
    PrintPending(pending);
    std::cout << "###########################" << std::endl;
}

int main()
{
    //设置2号信号的处理动作，不要让他终止
    signal(2, handler);


    sigset_t block ,oblock;
    //初始化位图每位为0
    sigemptyset(&block);
    sigemptyset(&oblock);

    //屏蔽信号
    sigaddset(&block,SIGINT);
    //正式设置内核屏蔽字
    sigprocmask(SIG_SETMASK,&block,&oblock);

    int cnt=15;
    while(true)
    {
        sigset_t pending;
        sigemptyset(&pending);

        //获取当前进程pending信号集
        sigpending(&pending);
        //不断打印pending信号集
        PrintPending(pending);
        cnt--;
        if(cnt==0)
        {
            //解除对信号的屏蔽
            std::cout<<"解除对2号信号屏蔽了！"<<std::endl;

            //位图置0即可
            sigprocmask(SIG_SETMASK, &oblock, nullptr);
        }
        sleep(1);
    }

    return 0;
}